/*=============================================================================
#    The element-comm is a tentative program used to test our ideas.           
#                       Copyright (C)  bgao                                    
#
#     This program is free software; you can redistribute it and/or            
#      modify it under the terms of the GNU General Public License             
#     as published by the Free Software Foundation; either version 2           
#         of the License, or (at your option) any later version.               
#
#     This program is distributed in the hope that it will be useful,          
#    but WITHOUT ANY WARRANTY; without even the implied warranty of           
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            
#             GNU General Public License for more details.                    
#
#    You should have received a copy of the GNU General Public License        
#     along with this program; if not, write to the Free Software             
#      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,             
#                       MA  02110-1301, USA.                                  
#==============================================================================
# $Id$ 
#
# $Author$ 
#
# $Revision$ 
#
# $Date$ 
#
# Description: 
#
=============================================================================*/
#include "rtos-wsn.h"
#include "ARM/arm-common.h"


typedef void (*isr_func)(void);

extern void isr_timer3_comp(void);
extern void isr_usart0_rx(void);
extern void isr_cc2420_fifop(void);


static void int_eint_sub_handler(void);
static void int_eint2_sub_handler(void);

static void int_lcd_sub_handler(void);
static void int_uart0_sub_handler(void);
static void int_uart1_sub_handler(void);
static void int_uart2_sub_handler(void);
static void int_adc_sub_handler(void);



/* default ISR */
void isr_default(void)
{
	__asm{nop}
}


/* int vector isr initlization */
const isr_func user_int_vector[32] ={
	isr_default,	/* EINT0 */
	isr_cc2420_fifop,	/* EINT1 */
	isr_default,	/* EINT2 */
	isr_default,	/* EINT3 */
	int_eint_sub_handler,	/* EINT4_7 */
	int_eint2_sub_handler,	/* EINT8_23 */
	isr_default,	/* Reserved */
	isr_default,	/* nBATT_FLT */
	isr_default,	/* INT_TICK */
	isr_default,	/* INT_WDT */
	isr_default,	/* INT_TIMER0 */
	isr_default,	/* INT_TIMER1 */
	isr_default,	/* INT_TIMER2 */
	isr_timer3_comp,	/* INT_TIMER3 */
	isr_default, 	/* INT_TIMER4 */
	int_uart2_sub_handler,	/* INT_UART2 */
	int_lcd_sub_handler,	/* INT_LCD */
	isr_default,	/* INT_DMA0 */
	isr_default,	/* INT_DMA1 */
	isr_default,	/* INT_DMA2 */
	isr_default,	/* INT_DMA3 */
	isr_default,	/* INT_SDI */
	isr_default,	/* INT_SPI0 */
	int_uart1_sub_handler,	/* INT_UART1 */
	isr_default,	/* Reserved */
	isr_default,	/* INT_USBD */
	isr_default,	/* INT_USBH */
	isr_default,	/* INT_IIC */
	int_uart0_sub_handler,	/* INT_UART0 */
	isr_default,	/* INT_SPI1 */
	isr_default,	/* INT_RTC */
	int_adc_sub_handler,	/* INT_ADC */
};
/*SUBSRCPND*/
const isr_func user_int_sub_vector[11] ={
	isr_usart0_rx,	/* INT_RXD0 */
	isr_default,	/* INT_TXD0 */
	isr_default,	/* INT_ERR0 */
	isr_default,	/* INT_RXD1 */
	isr_default,	/* INT_TXD1 */
	isr_default,	/* INT_ERR1 */
	isr_default,	/* INT_RXD2 */
	isr_default,	/* INT_TXD2 */
	isr_default,	/* INT_ERR2 */
	isr_default,	/* INT_TC */
	isr_default,	/* INT_ADC */
};
/*EINTPEND*/
const isr_func user_int_io_sub_vector[24] ={
	isr_default,	/* Reserved */
	isr_default,	/* Reserved */
	isr_default,	/* Reserved */
	isr_default,	/* Reserved */
	isr_default,	/* EINT4 */
	isr_default,	/* EINT5 */
	isr_default,	/* EINT6 */
	isr_default,	/* EINT7 */	
	isr_default,	/* EINT8 */
	isr_default,	/* EINT9 */
	isr_default,	/* EINT10 */
	isr_default,	/* EINT11 */	
	isr_default,	/* EINT12 */
	isr_default,	/* EINT13 */
	isr_default,	/* EINT14 */
	isr_default,	/* EINT15 */
	isr_default,	/* EINT16 */
	isr_default,	/* EINT17 */	
	isr_default,	/* EINT18 */
	isr_default,	/* EINT19 */
	isr_default,	/* EINT20 */
	isr_default,	/* EINT21 */	
	isr_default,	/* EINT22 */
	isr_default,	/* EINT23 */
};
/*LCDINTPND*/
const isr_func user_int_lcd_sub_vector[2] ={
	isr_default,	/* INT_FiCnt */
	isr_default,	/* INT_FrSyn */
};

#define INT_SUB_ADC		10
#define INT_SUB_TC		9
#define INT_SUB_ERR2	8
#define INT_SUB_TXD2	7
#define INT_SUB_RXD2	6
#define INT_SUB_ERR1	5
#define INT_SUB_TXD1	4
#define INT_SUB_RXD1	3
#define INT_SUB_ERR0	2
#define INT_SUB_TXD0	1
#define INT_SUB_RXD0	0

static void int_uart0_sub_handler(void)
{
	
	uint32 temp;
	temp = rSUBSRCPND & (~(rINTSUBMSK));
	if (temp & (1<<INT_SUB_RXD0) != 0 ){
		user_int_sub_vector[INT_SUB_RXD0]();
		return;
	}
	
	if (temp & (1<<INT_SUB_TXD0) != 0 ){
		user_int_sub_vector[INT_SUB_TXD0]();
		return;
	}	
	if (temp & (1<<INT_SUB_ERR0) != 0 ){
		user_int_sub_vector[INT_SUB_ERR0]();
		return;
	}

}

static void int_uart1_sub_handler(void)
{
		
	uint32 temp;
	temp = rSUBSRCPND & (~(rINTSUBMSK));

	if (temp & (1<<INT_SUB_RXD1) != 0 ){
		user_int_sub_vector[INT_SUB_RXD1]();
		return;
	}
	if (temp & (1<<INT_SUB_TXD1) != 0 ){
		user_int_sub_vector[INT_SUB_TXD1]();
		return;
	}
	if (temp & (1<<INT_SUB_ERR1) != 0 ){
		user_int_sub_vector[INT_SUB_ERR1]();
		return;
	}
}

static void int_uart2_sub_handler(void)
{
		
	uint32 temp;
	temp = rSUBSRCPND & (~(rINTSUBMSK));

	if (temp & (1<<INT_SUB_RXD2) != 0 ){
		user_int_sub_vector[INT_SUB_RXD2]();
		return;
	}
	if (temp & (1<<INT_SUB_TXD2) != 0 ){
		user_int_sub_vector[INT_SUB_TXD2]();
		return;
	}
	if (temp & (1<<INT_SUB_ERR2) != 0 ){
		user_int_sub_vector[INT_SUB_ERR2]();
		return;
	}
}
static void int_adc_sub_handler(void)
{
		
	uint32 temp;
	temp = rSUBSRCPND & (~(rINTSUBMSK));

	if (temp & (1<<INT_SUB_TC) != 0 ){
		user_int_sub_vector[INT_SUB_TC]();
		return;
	}
	if (temp & (1<<INT_SUB_ADC) != 0 ){
		user_int_sub_vector[INT_SUB_ADC]();
		return;
	}

}

#define INT_IO_SUB_EINT23	23
#define INT_IO_SUB_EINT22	22
#define INT_IO_SUB_EINT21	21
#define INT_IO_SUB_EINT20	20
#define INT_IO_SUB_EINT19	19
#define INT_IO_SUB_EINT18	18
#define INT_IO_SUB_EINT17	17
#define INT_IO_SUB_EINT16	16
#define INT_IO_SUB_EINT15	15
#define INT_IO_SUB_EINT14	14
#define INT_IO_SUB_EINT13	13
#define INT_IO_SUB_EINT12	12
#define INT_IO_SUB_EINT11	11
#define INT_IO_SUB_EINT10	10
#define INT_IO_SUB_EINT9	9
#define INT_IO_SUB_EINT8	9
#define INT_IO_SUB_EINT7	7
#define INT_IO_SUB_EINT6	6
#define INT_IO_SUB_EINT5	5
#define INT_IO_SUB_EINT4	4


static void int_eint_sub_handler(void)
{
	/*this routie set the highest priority to EINT4*/
	uint32 temp;
	temp = rEINTPEND & (~(rEINTMASK));
	if(temp & (1<<INT_IO_SUB_EINT4) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT4]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT5) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT5]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT6) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT6]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT7) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT7]();
		return;
	}
}

static void int_eint2_sub_handler(void)
{
	/*this routie set the highest priority to EINT8*/
	uint32 temp;
	temp = rEINTPEND & (~(rEINTMASK));
	
	if(temp & (1<<INT_IO_SUB_EINT8) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT8]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT9) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT9]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT10) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT10]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT11) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT11]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT12) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT12]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT13) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT13]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT14) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT14]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT15) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT15]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT16) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT16]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT17) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT17]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT18) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT18]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT19) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT19]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT20) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT20]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT21) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT21]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT22) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT22]();
		return;
	}
	if(temp & (1<<INT_IO_SUB_EINT23) != 0){
		user_int_io_sub_vector[INT_IO_SUB_EINT23]();
		return;
	}
}

#define INT_FrSyn	1
#define INT_FiCnt	0

static void int_lcd_sub_handler(void)
{
	if(rLCDINTPND & (1<<INT_FiCnt) != 0){
		user_int_lcd_sub_vector[INT_FiCnt]();
		return;
	}
	if(rLCDINTPND & (1<<INT_FrSyn) != 0){
		user_int_lcd_sub_vector[INT_FrSyn]();
		return;
	}	
}

void C_IRQHandler(void)
{
	/*make sure as soon as possible for timer interrupt*/
	user_int_vector[rINTOFFSET]();

}

